import { BenchmarkRunner } from "../../../utils/benchmarkTsSuite";
declare function print(arg:any) : string;

declare interface ArkTools{
	timeInUs(arg:any):number
}

let MAXSIZE = 1000000
function RunBuildInCall(){
    let startTime = ArkTools.timeInUs();
    
    for(var i=0;i<MAXSIZE;i++) {
        const reversed = "Run BuildIn Call ".split('').reverse().join('');
        const minVal = Math.min(10, 100);
        const maxVal = Math.max(10, 100);
        const absNum = Math.abs(-200);
        const roundedPi = Math.round(3.14159);
        const sqrtNum = Math.sqrt(25);
        const sinVal = Math.sin(Math.PI / 4);
        const cosVal = Math.cos(Math.PI / 3);
        const sortedNumbers = [10, 15.1, 158, 41, 6551, 12].sort();
        const reversedLetters = ["a", "b", "c", "d"].reverse();
    }
    let endTime = ArkTools.timeInUs();
    return (endTime - startTime) / 1000;
    
}
let runner1 = new BenchmarkRunner("BuildIn Call", RunComplexBuildInCall);
runner1.run();

interface CommandLineArgument {
    option: string | null;
    value: string | null;
}
    
class CommandLineArgumentsParser {
    public parseCommandLineArguments(): CommandLineArgument[] {
        const parsedArguments: CommandLineArgument[] = [];
        const args = process.argv.slice(2);
        for (let index = 0; index < args.length; index++) {
            const argument = args[index];
            if (argument.startsWith("-")) {
                const option = argument.slice(1);
                if (index + 1 < args.length && !args[index + 1].startsWith("-")) {
                    const value = args[index + 1];
                    parsedArguments.push({option, value});
                } else {
                    parsedArguments.push({option, value: null});
                }
            }
        }
        
        return parsedArguments;
    }
}

class TableProcessor {
    private table: string[][];
    
    constructor(initialTable: string[][]) {
        this.table = initialTable;
    }
    
    public run(): void {
        const parser = new CommandLineArgumentsParser();
        const args = parser.parseCommandLineArguments();
        
        for (const argument of args) {
            if (argument.option && argument.value) {
                switch (argument.option) {
                    case "add-row":
                        const rowValues = argument.value.split(",");
                        this.table.push(rowValues);
                        break;
                    case "remove-row":
                        const rowIndex = parseInt(argument.value);
                        if (!isNaN(rowIndex)) {
                            this.table.splice(rowIndex, 1);
                        } else {
                            console.log("Invalid remove-row argument. Expected integer value.");
                        }
                        break;
                    case "add-column":
                        const columnValues = argument.value.split(",");
                        for (let i = 0; i < columnValues.length; i++) {
                            const columnValue = columnValues[i];
                            if (i < this.table.length) {
                                this.table[i].push(columnValue);
                            } else {
                                console.log("add-column: Number of values exceeds number of rows.");
                                break;
                            }
                        }
                        break;
                    case "remove-column":
                        const columnIndex = parseInt(argument.value);
                        if (!isNaN(columnIndex)) {
                            for (let i = 0; i < this.table.length; i++) {
                                if (columnIndex < this.table[i].length) {
                                    this.table[i].splice(columnIndex, 1);
                                }
                            }
                        } else {
                            console.log("Invalid remove-column argument. Expected integer value.");
                        }
                        break;
                    case "sort":
                        const parts = argument.value.split(",");
                        if (parts.length === 2) {
                            const columnNumber = parseInt(parts[0]);
                            const columnOrder = parts[1];
                            if (!isNaN(columnNumber) && (columnOrder === "asc" || columnOrder === "desc")) {
                                const ascending = columnOrder.toLowerCase() === "asc";
                                this.sortTableByColumn(columnNumber, ascending);
                            } else {
                                console.log("Invalid sort argument format. Expected format: 'column_number,asc|desc'");
                            }
                        } else {
                            console.log("Invalid sort argument format. Expected format: 'column_number,asc|desc'");
                        }
                        break;
                    default:
                        console.log(`Unknown option: ${argument.option}`);
                        break;
                }
            }
        }
        
        for (const row of this.table) {
            // console.log(row.join("\t"));
            row.join("\t")
        }
    }
    
    private sortTableByColumn(columnNumber: number, ascending: boolean): void {
        this.table.sort((row1, row2) => {
            if (columnNumber < row1.length && columnNumber < row2.length) {
                const value1 = row1[columnNumber];
                const value2 = row2[columnNumber];
                
                const number1 = parseInt(value1);
                const number2 = parseInt(value2);
                
                if (!isNaN(number1) && !isNaN(number2)) {
                    return ascending ? (number1 - number2) : (number2 - number1);
                } else {
                    return ascending ? (value1.localeCompare(value2)) : (value2.localeCompare(value1));
                }
            } else {
                return 0;
            }
        });
    }
}

const initialTable: string[][] = [
    ["Data1", "Data2", "Data3"],
    ["I'm Data1 one", "I'm Data2 one", "I'm Data3 one"],
    ["I'm Data1 two", "I'm Data2 two", "I'm Data3 two"],
    ["I'm Data1 three", "I'm Data2 three", "I'm Data3 three"]
];

export function RunComplexBuildInCall(){
    let startTime = ArkTools.timeInUs();
    for(var i=0;i<MAXSIZE;i++){
        const processor = new TableProcessor(initialTable);
        processor.run();
    }
    let endTime = ArkTools.timeInUs();
    return (endTime - startTime) / 1000;
}

let runner2 = new BenchmarkRunner("Complex BuildIn Call", RunComplexBuildInCall);
runner2.run();